///////////////////////////////////////////////////////////////////////////////////////////////////
/// \file hf.h
///
/// \brief   header file for functions related to hartree fock calculations
///
///////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef PCPS_HF_HEADER
#define PCPS_HF_HEADER

#include <src/pcps.h>

namespace pcps {

  ///////////////////////////////////////////////////////////////////////////////////////////////////
  /// \brief   namespace for functions related to hartree fock calculations
  ///
  ///////////////////////////////////////////////////////////////////////////////////////////////////

  namespace hf {

    template <class S> void build_rdm1(const int n,
                                            const int np,
                                            const std::vector<S> & c,
                                                  std::vector<S> & x);

    template <class S> void build_fock(const int n,
                                            const std::vector<S> & ra,
                                            const std::vector<S> & rb,
                                            const std::vector<S> & oei,
                                            const std::vector<S> & tei,
                                                  std::vector<S> & f);

    template <class S> void diagonalize_fock(const int n,
                                                  const int np,
                                                  const std::vector<S> & f,
                                                  std::vector<double> & eval,
                                                  std::vector<S> & c);

    template <class S> void build_ints(const pcps::Hamiltonian<S> & ham,
                                            const int n,
                                            std::vector<S> & oei_a,
                                            std::vector<S> & oei_b,
                                            std::vector<S> & tei);

    template <class S> S alpha_energy(const int n,
                                                const std::vector<S> & oei,
                                                const std::vector<S> & f,
                                                const std::vector<S> & rdm);

    template <class S> void print_orbitals(const int n,
                                                const int na,
                                                const std::vector<double> & evals,
                                                const std::vector<S> & c,
                                                const std::string & str);

    template <class S> void uhf(const int n,
                                     const int na,
                                     const int nb,
                                     const pcps::Hamiltonian<S> & ham,
                                     const std::vector<double> & bias,
                                     const double bias_decay,
                                     const double thresh,
                                     const int maxit,
                                     std::vector<S> & ca,
                                     std::vector<S> & cb,
                                     S & energy);

  } // end namespace hf

} // end namespace pcps

#endif
